﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using NP.BPMReportPlatform.DBHelper;
using NP.BPMReportPlatform.Entities.BPM_Business;
using NP.BPMReportPlatform.Entities.BPM_Platform;
using NP.BPMReportPlatform.StandardApprovalFlow.Dto;
using NP.BPMReportPlatform.Utils;
using SqlSugar;
using Volo.Abp.Application.Dtos;

namespace NP.BPMReportPlatform.StandardApprovalFlow
{
    /// <summary>
    /// 通用审批流程服务
    /// </summary>
    public class StandardApprovalAppService : BPMReportPlatformAppService, IStandardApprovalAppService
    {
        private readonly SqlSugarClient _db, _dbPlatform;
        private readonly IBPMUtilsAppService _bPMUtilsApp;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="sqlSugarAppService"></param>
        public StandardApprovalAppService(ISqlSugarAppService sqlSugarAppService, IBPMUtilsAppService bPMUtilsApp)
        {
            _db = sqlSugarAppService.GetBusinessInstance();
            _dbPlatform = sqlSugarAppService.GetPlatformInstance();
            _bPMUtilsApp = bPMUtilsApp;
        }

        /// <summary>
        /// 获取Queryable
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        private ISugarQueryable<GetStandardApprovalOutput> GetQueryable(GetStandardApprovalInput input)
        {
            var currentUserId = Guid.Empty;
            if (!input.IsQueryAll)
            {
                var currentUserDto = _dbPlatform.Queryable<Users>().Where(x => x.WorkNumber.Equals(CurrentUser.UserName)).First();
                if (currentUserDto != null)
                {
                    currentUserId = currentUserDto.UserId;
                }
            }
            var listQueryable = _db.Queryable<StandardApproval, BusinessProcessesNew>((st, bu) => new JoinQueryInfos(JoinType.Left, st.InstanceId == bu.InstanceId))
                          .WhereIF(!string.IsNullOrWhiteSpace(input.Title), st => st.Title.Contains(input.Title))
                          .WhereIF(!string.IsNullOrWhiteSpace(input.InstanceNumber), st => st.InstanceId.Equals(input.InstanceNumber))
                          .WhereIF(!input.OrderStatus.IsNullOrEmpty(), (st, bu) => SqlFunc.ContainsArray<string>(input.OrderStatus.ToArray(), bu.ProcessStatusCode))
                          .WhereIF(!string.IsNullOrWhiteSpace(input.FlowType), st => st.FlowType.Equals(input.FlowType))
                          .WhereIF(!string.IsNullOrWhiteSpace(input.AddUserName), st => st.AddUserName.Equals(input.AddUserName))
                          .WhereIF(!input.IsQueryAll, st => st.AddUserId.Equals(currentUserId))
                          .WhereIF(input.StartCreationTime != null && input.EndCreationTime != null, st => st.AddTime >= input.StartCreationTime && st.AddTime <= input.EndCreationTime)
                          .WhereIF(!string.IsNullOrWhiteSpace(input.Area), (st, bu) => st.Area.Equals(input.Area))
                          .WhereIF(!string.IsNullOrWhiteSpace(input.NinetyNo), (st, bu) => st.NinetyNo.Equals(input.NinetyNo))
                          .WhereIF(!string.IsNullOrWhiteSpace(input.ApplicationReason), (st, bu) => st.ApplicationReason.Equals(input.ApplicationReason))
                          .WhereIF((input.AdditionalFreight) is > 0, (st, bu) => st.AdditionalFreight.Equals(input.AdditionalFreight))
                          .Select((st, bu) =>
                              new GetStandardApprovalOutput()
                              {
                                  InstanceNumber = st.InstanceId,
                                  Title = st.Title,
                                  Content = st.Content,
                                  AddUserName = st.AddUserName,
                                  FlowType = st.FlowType,
                                  AddTime = st.AddTime,
                                  OrderStatus = bu.ProcessStatusName,
                                  TransportNumber = st.TransportNumber,
                                  Area = st.Area,
                                  AdditionalFreight = st.AdditionalFreight,
                                  NinetyNo = st.NinetyNo,
                                  ApplicationReason = st.ApplicationReason,
                              }).OrderBy(st => st.AddTime, OrderByType.Desc);
            return listQueryable;
        }

        /// <summary>
        /// 查询数据
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<GetStandardApprovalOutput>> GetAllAsync(GetStandardApprovalInput input)
        {
            RefAsync<int> totalCount = 0;

            var listQueryable = GetQueryable(input);

            var listViewDto = await listQueryable.ToPageListAsync(input.PageIndex, input.PageSize, totalCount);

            var userDto = await _dbPlatform.Queryable<Users>().Where(x => x.WorkNumber.Equals(CurrentUser.UserName)).SingleAsync();

            listViewDto.ForEach(x => x.Url = _bPMUtilsApp.GetProcessUrl(x.InstanceNumber, userDto.UserId.ToString()));

            //返回结果
            return new PagedResultDto<GetStandardApprovalOutput>()
            {
                TotalCount = totalCount,
                Items = listViewDto
            };
        }

        /// <summary>
        /// 导出数据
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<GetStandardApprovalOutput>> ExportAsync(GetStandardApprovalInput input)
        {
            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToListAsync();
            return listViewDto;
        }

        /// <summary>
        /// 导出有运单的通用审批数据
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<ExportStandardApprovalOutput>> ExportTransportAsync(GetStandardApprovalInput input)
        {
            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToListAsync();
            var exportList = ObjectMapper.Map<List<GetStandardApprovalOutput>, List<ExportStandardApprovalOutput>>(listViewDto);
            return exportList;
        }

        /// <summary>
        /// 导出不足吨位发货
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<ExportStandardApprovalBZDWOutput>> ExportBZDWAsync(GetStandardApprovalInput input)
        {
            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToListAsync();
            var exportList = ObjectMapper.Map<List<GetStandardApprovalOutput>, List<ExportStandardApprovalBZDWOutput>>(listViewDto);
            return exportList;
        }

        /// <summary>
        /// 导出加急包车
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<ExportStandardApprovalJJBCOutput>> ExportJJBCAsync(GetStandardApprovalInput input)
        {
            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToListAsync();
            var exportList = ObjectMapper.Map<List<GetStandardApprovalOutput>, List<ExportStandardApprovalJJBCOutput>>(listViewDto);
            return exportList;
        }
        /// <summary>
        /// 导出90单发货
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<ExportStandardApproval90Output>> Export90Async(GetStandardApprovalInput input)
        {
            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToListAsync();
            var exportList = ObjectMapper.Map<List<GetStandardApprovalOutput>, List<ExportStandardApproval90Output>>(listViewDto);
            return exportList;
        }
    }
}
